package org.example.quartz.BIP;

import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.UtilService;
import org.example.quartz.task.QuartzTaskJob;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class UserQuartz_BIP implements QuartzTaskJob {

    /**
     * 用户接口
     * 接口地址：GSCloud文档3.10
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncUser
     **/
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        try {
            Map<String, Object> gsMap = DataSourceUtil.getGS();
            //全局接口配置
            String IP = (String) gsMap.get("IP");
            String PORT = (String) gsMap.get("PORT");
            String ECC = (String) gsMap.get("ECC");
            String Bearer = (String) gsMap.get("Bearer");
            //日志
            LogService loginfo = SpringUtil.getBean(LogService.class);
            //orgService
            OrgService orgService = SpringUtil.getBean(OrgService.class);
            //orgService
            UtilService utilService = SpringUtil.getBean(UtilService.class);

            //传入变量 lastTime 最后抓取时间
            //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
            //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
            //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
            //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
            //查询脚本
            JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
            //轮询用户
            List<Map<String, Object>> yyztCodeMap = orgService.selectJTZtCode(jdbcTemplate);
            for (int x = 0; x < yyztCodeMap.size(); x++) {
                //查询脚本
                String methodName = "UserQuartz";
                methodName += (String) yyztCodeMap.get(x).get("GSCODE");
                //1、查询时间
                String ts = utilService.getTs(methodName, jdbcTemplate);
                //2、根据时间查询数据集 (停用和删除的过滤掉，暂不考虑，线下处理)
                String selectSQL = "SELECT  \n" +
                        "                US.USER_CODE AS CODE, \n" +
                        "                US.USER_NAME AS NAME, \n" +
                        "                ORG.CODE AS ORGCODE, \n" +
                        "                '' AS CONTACTINFO, \n" +
                        "                '' AS EMAIL, \n" +
                        "                '' AS IDNUMBER, \n" +
                        "                PSN.SEX AS SEX, \n" +
                        "                ' ' AS SECLEVEL, \n" +
                        "                US.TS AS TS, \n" +
                        "                US.USER_NOTE AS REMARK \n" +
                        "                FROM  \n" +
                        " " + utilService.getOracle() + ".SM_USER"+utilService.getHZ()+" US \n" +
                        "                LEFT JOIN " + utilService.getOracle() + ".ORG_ORGS"+utilService.getHZ()+" ORG ON US.PK_ORG = ORG.PK_ORG \n" +
                        "                LEFT JOIN " + utilService.getOracle() + ".BD_PSNDOC"+utilService.getHZ()+" PSN ON US.PK_PSNDOC = PSN.PK_PSNDOC \n" +
                        "                WHERE  \n" +
                        "               (US.DR =0 OR US.DR IS NULL)\n" +
                        "                AND \n" +
                        "                US.TS >'" + ts + "' \n" +
                        "                ORDER BY TS ASC";
                System.out.println(selectSQL);
                //查询数据，根据数据结果推送给GS浪潮
                Session oracleSession = DataSourceUtil.getLSOracleSession();
                List<Entity> query = oracleSession.query(selectSQL);
                if (query.size() > 0) {
                    String gsCode = (String) yyztCodeMap.get(x).get("gsCode");
                    for (Map<String, Object> gSmap : query) {
                        /**
                         * GS规则：系统用户接口，用户编号需要保持集团内唯一，传递是需要在原人员编号前拼接上单位编号，保证集团内唯一
                         *
                         * */
                        String GsJson =
                                "{\n" +
                                        "    \"CODE\":\"" + gsCode + gSmap.get("CODE") + "\",\n" +
                                        "    \"NAME\":\"" + gSmap.get("NAME") + "\",\n" +
                                        "    \"ORGCODE\":\"" + gsCode + "\",\n" +
                                        "    \"CONTACTINFO\":\"" + gSmap.get("CONTACTINFO") + "\",\n" +
                                        "    \"EMAIL\":\"" + gSmap.get("EMAIL") + "\",\n" +
                                        "    \"IDNUMBER\":\"" + gSmap.get("IDNUMBER") + "\",\n" +
                                        "    \"SEX\":\"" + gSmap.get("SEX") + "\",\n" +
                                      //  "    \"SECLEVEL\":\"" + gSmap.get("SECLEVEL") + "\",\n" +
                                        "    \"SECLEVEL\":\"" + "PUBLIC" + "\",\n" +
                                        "    \"YCODE\":\"" + gSmap.get("CODE") + "\",\n" +
                                        "    \"YNAME\":\"" + gSmap.get("NAME") + "\",\n" +
                                        "    \"REMARK\":\"" + gSmap.get("REMARK") + "\"\n" +
                                        "}";
                        GsJson = GsJson.replace("null", "");

                        GsJson = GsJson.replace("/", "-")
                                .replace("（", "\\（")
                                .replace("）", "\\）")
                                .replace("(", "\\(")
                                .replace(")", "\\)");
                        //调用GS接口，推送给GS浪潮，获取返回值;
                        //1、推送用户档案
                        String gsUrl = IP + ":" + PORT + "/api/jg/syncbddata/v1.0/bdsyncinterface/syncUser";
                        String returnMSG = HttpRequest.post(gsUrl)
                                .header("Content-Type", "application/json")
                                .header("Accept-Language", "zh-CHS")
                                .header("X-ECC-Current-Tenant", ECC)
                                .header("Authorization", Bearer).timeout(200000)
                                .body(GsJson).execute().body();
                        System.out.println(methodName+"returnMSG:" + returnMSG);
                        if (!returnMSG.isEmpty()) {
                            String logInsert = "";
                            JSONObject returnObj = JSONObject.parseObject(returnMSG);
                            //成功
                            if (ObjectUtils.isEmpty(returnObj.get("Code")) && ("").equals(returnObj.get("Code"))) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", (String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            } else if (ObjectUtils.isEmpty(returnObj.get("code")) && ("").equals(returnObj.get("code"))) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", (String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            } else if ("0".equals(returnObj.get("code"))) {
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "成功", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                                //失败
                            } else if ("1".equals(returnObj.get("code"))) {
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "失败", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }else {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "",(String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }
                        }
                    }
                } else {
                    System.out.printf(methodName + "暂无数据推送");
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //关闭链接
            DataSourceUtil.closeOracleSession();
            DataSourceUtil.closeMysqlSession();
        }

    }
}

